From: Niklas Laxström Date: Mon, 2 Jun 2014 18:34:52 +0000 (+0000) Subject: PrefixSearch (ApiOpenSearch) now supports searching in multiple namespaces X-Git-Tag: 1.31.0-rc.0~15273^2~1 X-Git-Url: http://git.cyclocoop.org/%7D%7Cconcat%7B?a=commitdiff_plain;h=0e054bbf1a955b02afd4feaa04063c841e19a569;p=lhc%2Fweb%2Fwiklou.git PrefixSearch (ApiOpenSearch) now supports searching in multiple namespaces I thought there was just an issue with capitalization, but in fact the code explicitly only searched one namespace anyway. Fixed that while taking capitalization differences in namespaces into account. Bug: 65752 Bug: 30323 Change-Id: I3487bb69eae1867832e0ec9ece497538eca32a2a --- diff --git a/includes/PrefixSearch.php b/includes/PrefixSearch.php index a796d35723..15d48cb82a 100644 --- a/includes/PrefixSearch.php +++ b/includes/PrefixSearch.php @@ -51,32 +51,33 @@ abstract class PrefixSearch { */ public function search( $search, $limit, $namespaces = array() ) { $search = trim( $search ); - if ( $search == '' ) { - return array(); // Return empty result + if ( $search === '' ) { + return array(); } + $namespaces = $this->validateNamespaces( $namespaces ); - // Find a Title which is not an interwiki and is in NS_MAIN - $title = Title::newFromText( $search ); - if ( $title && !$title->isExternal() ) { - $ns = array( $title->getNamespace() ); - if ( $ns[0] == NS_MAIN ) { - $ns = $namespaces; // no explicit prefix, use default namespaces - } - return $this->searchBackend( - $ns, $title->getText(), $limit ); + // Is this a namespace prefix? Start listing all pages in it. + $title = Title::newFromText( $search . 'Dummy' ); + if ( $title + && $title->getText() === 'Dummy' + && !$title->inNamespace( NS_MAIN ) + && !$title->isExternal() + ) { + $this->searchBackend( array( $title->getNamespace() ), '', $limit ); } - // Is this a namespace prefix? - $title = Title::newFromText( $search . 'Dummy' ); - if ( $title && $title->getText() == 'Dummy' - && $title->getNamespace() != NS_MAIN - && !$title->isExternal() ) - { - $namespaces = array( $title->getNamespace() ); - $search = ''; + // Explicit namespace prefix? Limit search to that namespace. + $title = Title::newFromText( $search ); + if ( $title + && !$title->isExternal() + && !$title->inNamespace( NS_MAIN ) + ) { + // This will convert first letter to uppercase if appropriate for the namespace + $this->searchBackend( array( $title->getNamespace() ), $title->getText(), $limit ); } + // Search in all requested namespaces return $this->searchBackend( $namespaces, $search, $limit ); } @@ -219,28 +220,33 @@ abstract class PrefixSearch { * @return array Array of Title objects */ protected function defaultSearchBackend( $namespaces, $search, $limit ) { - $ns = array_shift( $namespaces ); // support only one namespace - if ( in_array( NS_MAIN, $namespaces ) ) { - $ns = NS_MAIN; // if searching on many always default to main + $dbr = wfGetDB( DB_SLAVE ); + + // Construct suitable prefix for each namespace, they might differ + $prefixes = array(); + foreach ( $namespaces as $ns ) { + $title = Title::makeTitleSafe( $ns, $search ); + $prefix = $title ? $title->getDBkey() : ''; + $prefixes[$prefix][] = $ns; + } + + $conds = array(); + foreach ( $prefixes as $prefix => $nss ) { + $conds[] = $dbr->makeList( array( + 'page_namespace' => $nss, + 'page_title' . $dbr->buildLike( $prefix, $dbr->anyString() ), + ), LIST_AND ); } - $t = Title::newFromText( $search, $ns ); - $prefix = $t ? $t->getDBkey() : ''; - $dbr = wfGetDB( DB_SLAVE ); $res = $dbr->select( 'page', array( 'page_id', 'page_namespace', 'page_title' ), - array( - 'page_namespace' => $ns, - 'page_title ' . $dbr->buildLike( $prefix, $dbr->anyString() ) - ), + $dbr->makeList( $conds, LIST_OR ), __METHOD__, array( 'LIMIT' => $limit, 'ORDER BY' => 'page_title' ) ); - $srchres = array(); - foreach ( $res as $row ) { - $srchres[] = Title::newFromRow( $row ); - } - return $srchres; + + // Shorter than a loop, and doesn't break class api + return iterator_to_array( TitleArray::newFromResult( $res ) ); } /**